home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / cfixvb / curr2vb.asm next >
Assembly Source File  |  1991-09-06  |  3KB  |  137 lines

  1.     page ,132
  2.     .model large, basic
  3.     .286
  4. comment |
  5.     This routine can help you maintain currency variables to a fixed
  6.     number of decimal places.  This is the VB version of the code.
  7.  
  8.    ----------------------------------------------------------------------
  9.     Written by Jim Mack, CIS 76630,2012, bix "jsmack"
  10.     Copyright 1991, Editing Services Co.  All rights reserved.
  11.  
  12.     Free for non-commercial use: commercial rights freely granted on 
  13.       written request, with acknowledgement of copyright.
  14.    ----------------------------------------------------------------------
  15.  
  16.     DECLARE SUB CurrFix lib "currfix.dll" (CurrVal@, ByVal Places%, ByVal Truncate%)
  17.       Adjusts the passed Currency variable (if required) to remove one
  18.       or more digits to the right of the decimal point.
  19.  
  20.     CurrVal@ is directly modified, not returned as a function result.
  21.  
  22.     Places% may be 0 to 3 and will result in a value with the indicated
  23.     number of digits beyond the decimal point.  Other values are ingored
  24.     with CurrVal@ left unchanged.
  25.  
  26.     If Truncate% is non-zero the excess places are simply removed, 
  27.     otherwise the value is rounded using traditional financial rounding.
  28.  
  29.     Performs the equivalent of the following Basic code:
  30.  
  31.       CVal@ = INT((CVal@ * (10^n)) + .5) / (10^n)
  32.  
  33.     Floating point is avoided for maximum speed.
  34.    ----------------------------------------------------------------------
  35.     |
  36.  
  37. by    equ <byte ptr>        ;; convenient shorthand macros
  38. wo    equ <word ptr>
  39. bit    equ <1 shl>
  40.  
  41. EPNegate    MACRO MemArg    ;; extended-precision integer unary negate
  42.  
  43.     xor    ax, ax
  44.     neg    wo MemArg
  45.     not    wo MemArg+2
  46.     not    wo MemArg+4
  47.     not    wo MemArg+6
  48.     cmc
  49.     adc    MemArg+2, ax
  50.     adc    MemArg+4, ax
  51.     adc    MemArg+6, ax
  52.  
  53.         ENDM
  54. ;---------------------------------------------------------------------------
  55.  
  56.     .code
  57.  
  58. PTable        dw    10000, 1000, 100, 10
  59.  
  60. CurrFix        PROC uses di si, currval:dword, places, truncate
  61.         LOCAL sgn
  62.  
  63.     lds    si, currval        ; --> currency value
  64.     mov    sgn, 0
  65.     test    by 7[si], bit 7        ; negative?
  66.     jz    @f
  67.     dec    sgn            ; yes, indicate for exit
  68.     EPNegate [si]            ; and make positive (negate -number)
  69. @@:
  70.     mov    bx, places
  71.     cmp    bx, 0
  72.     jl    cferr
  73.     cmp    bx, 3
  74.     jna    @f            ; all OK
  75.  
  76. cferr:    jmp    cfx90            ; ignore if > 3 or < 0
  77.  
  78. @@:    add    bx, bx
  79.     mov    cx, PTable[bx]
  80.     mov    ax, 6[si]
  81.     xor    dx, dx
  82.     div    cx
  83.     mov    6[si], ax
  84.     mov    ax, 4[si]
  85.     div    cx
  86.     mov    4[si], ax
  87.     mov    ax, 2[si]
  88.     div    cx
  89.     mov    2[si], ax
  90.     mov    ax, [si]
  91.     div    cx
  92.     mov    [si], ax        ; value MOD [CX] in DX now
  93.     shr    cx, 1
  94.     xor    ax, ax
  95.     cmp    truncate, ax        ; round or truncate?
  96.     jne    @f            ; truncate: skip next test
  97.     cmp    dx, cx            ; clear carry if remainder >= half
  98.     jc    @f
  99.     cmc
  100.     adc    [si], ax
  101.     adc    2[si], ax
  102.     adc    4[si], ax
  103.     adc    6[si], ax
  104.     ;
  105.     ; Multiplying will restore zeroes to the last places
  106.     ;
  107. @@:
  108.     shl    cx, 1            ; restore divisor as multiplier
  109.     mov    ax, [si]
  110.     mul    cx
  111.     mov    di, dx            ; accumulate partial product
  112.     mov    [si], ax
  113.     mov    ax, 2[si]
  114.     mul    cx
  115.     mov    bx, dx
  116.     mov    2[si], ax
  117.     mov    ax, 4[si]
  118.     mul    cx
  119.     push    dx
  120.     mov    4[si], ax
  121.     mov    ax, 6[si]
  122.     mul    cx
  123.     mov    6[si], ax
  124.     pop    dx
  125.     add    2[si], di        ; shifted partial product in DX:BX:DI
  126.     adc    4[si], bx
  127.     adc    6[si], dx
  128.     cmp    sgn, 0            ; was negative?
  129.     je    cfx90
  130.     EPNegate [si]            ; if so, make negative again
  131. cfx90:
  132.     ret
  133.  
  134. CurrFix        ENDP
  135.  
  136.     END
  137.